<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use DB;

class MidAutumnLog extends Model
{
    protected $table = 'mid_autumn_log';
    public $timestamps = false;

    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'c_id');
    }

    const PRIZE_YES = 1;
    const PRIZE_NO = 2;

    const TYPE_NONE = 0;
    const TYPE_IPHONE = 1;
    const TYPE_LAMP = 2;
    const TYPE_HEADSET = 3;
    const TYPE_REDBAG1 = 4;
    const TYPE_REDBAG2 = 5;


    const DAY_ONE_NUM = 20;
    const DAY_TWO_NUM = 10;
    const DAY_THREE_NUM = 15;


    const ALL_NUM = 42;
    const REDBAG_ALL = 84;
    const RADBAG_AVERAGE = 2;

    /**
     * 中一等奖或者二等奖
     * @param $reward
     * @return string
     */
    static function RewardMsg($reward)
    {
        return <<<TEXT
您好!
感谢您参与康侣首届兔兔吃月饼手游争霸赛活动。
祝贺您在此活动中获得$reward 。
请您于2018年9月25日—9月29日9：00-17:30，
前往保定高新技术产业园区7A-402，康侣网络科技有限公司领取奖品。
联系电话：0312-6670755。
TEXT;
    }

    /**
     * 没有中奖
     * @return string
     */
    static function UnRewardMsg()
    {
        return <<<TEXT
您刚刚参与了康侣中秋节活动抽奖,但是很遗憾没有中奖
TEXT;
    }

    /**
     * 抽中红包
     * @param $number
     * @return string
     */
    static function RedBagMsg($number)
    {
        return <<<TEXT
您刚刚参与了康侣中秋节活动抽奖,抽中现金红包 $number 元.
TEXT;

    }


    /**
     * 获奖记录
     * @return array
     */
    static function DrawList()
    {
        $data = [];
        $lists = MidAutumnLog::with('user:c_id,name,c_avatar')->where('is_prize', self::PRIZE_YES)->get();
        if (count($lists) > 0) {
            foreach ($lists as $list) {
                $data[] = [
                    'id' => $list->id,
                    'user_name' => $list->user->name,
                    'user_avatar' => $list->user->c_avatar,
                    'type' => $list->type,
                    'number' => $list->number,
                ];
            }
        }
        return success(compact('data'));
    }


    /**
     * 没中奖
     * @param $user_id
     * @return array
     */
    static function NotPrized($user_id)
    {
        DB::beginTransaction();

        //添加记录
        $log = new MidAutumnLog();
        $log->user_id = $user_id;
        $log->created_at = time();
        if (!$log->save()) {
            DB::rollBack();

            return error('出错了');
        }

        //发送消息
        $msg = Wechat::SendMsg($user_id, self::UnRewardMsg());
        if ($msg['code'] !== 200) {
            DB::rollBack();

            return $msg;
        }

        DB::commit();

        return success();
    }

    /**
     * 中奖
     * @param $user_id
     * @param $type
     * @param $number
     * @return array
     */
    static function PrizedBack($user_id, $type, $number)
    {
        $time = time();
        DB::beginTransaction();

        $log = new MidAutumnLog();
        $log->user_id = $user_id;
        $log->type = $type;
        $log->number = $number;
        $log->is_prize = self::PRIZE_YES;
        $log->created_at = $time;
        if (!$log->save()) {
            DB::rollBack();
            return error('出错了');
        }

        //打钱
        $user = User::select('wechat', 'name')->where('c_id', $user_id)->first();
        $app = Wechat::PayConfig();
        $result = $app->transfer->toBalance([
            'partner_trade_no' => 'KL' . time() . $user_id, // 商户订单号，需保持唯一性(只能是字母或者数字，不能包含有符号)
            'openid' => $user->wechat,
            'check_name' => 'NO_CHECK', // NO_CHECK：不校验真实姓名, FORCE_CHECK：强校验真实姓名
            're_user_name' => $user->name, // 如果 check_name 设置为FORCE_CHECK，则必填用户真实姓名
            'amount' => bcmul($number, 100), // 企业付款金额，单位为分
            'desc' => '康侣活动红包', // 企业付款操作说明信息。必填
        ]);
        //校验
        if ($result['return_code'] !== 'SUCCESS') {
            DB::rollBack();
            return error('出错了');
        }
        if ($result['result_code'] !== 'SUCCESS') {
            DB::rollBack();
            return error('出错了');
        }
        DB::commit();

        return success();
    }


    /**
     * 抽奖次数
     * @param $user_id
     * @return int
     */
    static function LuckDrawTimes($user_id)
    {
        $times = 0;
        $integrals = MidAutumnIntegral::where('user_id', $user_id)->pluck('number')->toArray();
        if (count($integrals)) {
            foreach ($integrals as $integral) {
                $times += floor($integral / MidAutumnIntegral::PRIZE_NUMBER);
            }
        }
        return $times;
    }


    /**
     * 能否中奖
     * @return bool
     */
    static function IsDraw()
    {
        //今天的起止时间
        $beginToday = mktime(0, 0, 0, date('m'), date('d'), date('Y'));
        $endToday = mktime(0, 0, 0, date('m'), date('d') + 1, date('Y')) - 1;
        //如果有30个抽奖的了  就中不了了
        //当天的抽奖次数
        $logs = MidAutumnLog::whereBetween('created_at', [$beginToday, $endToday])->count();
        if ($logs >= 70) {
            return false;
        }
        //当天抽中的次数
        $draw_logs = MidAutumnLog::whereBetween('created_at', [$beginToday, $endToday])->where('is_prize', self::PRIZE_YES)->count();
        //抽奖次数过了20  但是不足5个中奖
        if ($logs >= 20 && $draw_logs <= 5) {
            return $draw_logs;
        }
        //抽奖次数过了50  但是不足10个中奖
        if ($logs >= 50 && $draw_logs <= 10) {
            return $draw_logs;
        }
        if ($draw_logs >= 15) {
            return false;
        }
        //剩余可中奖次数
        $last_times = 15 - $draw_logs;
        //剩余可抽奖次数
        $last_luck = 70 - $logs;
        //剩余可中奖次数 >= 30 - 已抽奖次数   必中
        if ($last_times >= $last_luck) {
            return $draw_logs;
        }
        if (mt_rand(0, $last_luck * 10000) <= $last_times * 10000 * 2) {
            return $draw_logs;
        }
        return false;
    }


    /**
     * 选择抽中什么奖品
     * @param $draw_logs
     * @return array
     */
    static function Reward($draw_logs)
    {
        //日期
        $time = time();
        $month = intval(date('m', $time));
        $date = intval(date('d', $time));
        //月份
        if ($month === 10) {
            //1号
            if ($date === 1) {
                if ($draw_logs === 8) {
                    return ['type' => self::TYPE_REDBAG1, 'number' => 8.88];
                }
                //2号
            } else if ($date === 2) {
                if ($draw_logs === 6) {
                    return ['type' => self::TYPE_REDBAG1, 'number' => 6.66];
                }

                //3号
            } else if ($date === 3) {
                if ($draw_logs === 7) {
                    return ['type' => self::TYPE_REDBAG1, 'number' => 6.66];
                }
            }
        }

        //非固定
        //  计算剩余随机红包总金额和剩余包数 算出平均值  与总平均值作比较
        $number_all = bcsub(self::REDBAG_ALL, MidAutumnLog::where('type', self::TYPE_REDBAG2)->sum('number'), 2);
        if ($number_all <= 0) {
            return ['type' => self::TYPE_REDBAG2, 'number' => 1];
        }
        $n = MidAutumnLog::where('type', self::TYPE_REDBAG2)->count();
        if ($n >= 42) {
            return ['type' => self::TYPE_REDBAG2, 'number' => 1];
        }

        $ave = bcdiv($number_all, (42 - $n), 2);
        if ($ave <= self::RADBAG_AVERAGE) {
            $number = bcdiv(mt_rand(100, self::RADBAG_AVERAGE * 100), 100, 2);
        } else {
            $number = bcdiv(mt_rand(self::RADBAG_AVERAGE * 100, 300), 100, 2);
        }
        return ['type' => self::TYPE_REDBAG2, 'number' => $number];
    }


    /**
     * 抽奖
     * @param $user_id
     * @return array
     * @throws \Exception
     */
    static function Draw($user_id)
    {
        DB::beginTransaction();
        //减少抽奖次数
        $integralMul = MidAutumnIntegral::IntegralMul($user_id);
        if ($integralMul['code'] !== 200) {
            DB::rollBack();

            return $integralMul;
        }
        //抽奖次数
        $luck_times = MidAutumnLog::LuckDrawTimes($user_id);

        //是否中奖
        $is_prize = self::IsDraw();
        if (!is_numeric($is_prize)) {
            //没中奖
            $result = self::NotPrized($user_id);
            if ($result['code'] !== 200) {
                DB::rollBack();

                return $result;
            }

            DB::commit();

            $data = ['type' => self::TYPE_NONE, 'luck_times' => $luck_times];
            return success(compact('data'));
        }
        //选择奖品
        $reward = self::Reward($is_prize);
        $prized = self::Prized($user_id, $reward['type'], $reward['number']);
        if ($prized['code'] !== 200) {
            DB::rollBack();

            return $prized;
        }
        $data = ['type' => $reward['type'], 'number' => $reward['number'], 'luck_times' => $luck_times];
        DB::commit();

        return success(compact('data'));

    }

    /**
     * 中奖处理
     * @param $user_id
     * @param $type
     * @param $number
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     * @throws \Exception
     */
    static function Prized($user_id, $type, $number)
    {
        DB::beginTransaction();

        $time = time();
        //数据库更新
        $log = new MidAutumnLog();
        $log->user_id = $user_id;
        $log->is_prize = self::PRIZE_YES;
        $log->type = $type;
        $log->number = $number;
        $log->created_at = $time;
        if (!$log->save()) {
            DB::rollBack();

            return error('出错了,请联系管理员');
        }

        //发送消息
        if ($type === self::TYPE_LAMP) {
            $message = self::RewardMsg('康众护眼灯');
        } else if ($type === self::TYPE_HEADSET) {
            $message = self::RewardMsg('耳机');
        } else {
            $message = self::RedBagMsg($number);
        }


        $msg = Wechat::SendMsg($user_id, $message);
        if ($msg['code'] !== 200) {
            DB::rollBack();

            return $msg;
        }

        //打钱
        $m = date('m', $time);
        $d = date('d', $time);
        if (intval($m) === 10 && in_array($d, [1, 2, 3])) {
            $user = User::select('wechat', 'name')->where('c_id', $user_id)->first();
            $app = Wechat::PayConfig();
            $result = $app->transfer->toBalance([
                'partner_trade_no' => 'KL' . time() . $user_id, // 商户订单号，需保持唯一性(只能是字母或者数字，不能包含有符号)
                'openid' => $user->wechat,
                'check_name' => 'NO_CHECK', // NO_CHECK：不校验真实姓名, FORCE_CHECK：强校验真实姓名
                're_user_name' => $user->name, // 如果 check_name 设置为FORCE_CHECK，则必填用户真实姓名
                'amount' => bcmul($number, 100), // 企业付款金额，单位为分
                'desc' => '康侣活动红包', // 企业付款操作说明信息。必填
            ]);
            //校验
            if ($result['return_code'] !== 'SUCCESS') {
                DB::rollBack();

                return error($result['return_msg']);
            }
            if ($result['result_code'] !== 'SUCCESS') {
                DB::rollBack();

                return error($result['err_code_des']);
            }
        }
        DB::commit();

        return success();
    }

}
